package ar.edu.itba.jMEBowling.scenario;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;

import ar.edu.itba.jMEBowling.Runner;
import ar.edu.itba.jMEBowling.scoring.Scoring;
import ar.edu.itba.jMEBowling.utils.Helpers;

import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.light.PointLight;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jmex.physics.PhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.material.Material;

public class Scenario {

	private Properties properties;
	// private StaticPhysicsNode staticNode;
	private StaticPhysicsNode staticNode;
	/*
	 * private StaticPhysicsNode leftWallNode; private StaticPhysicsNode
	 * rightWallNode; private StaticPhysicsNode floorNode; private
	 * StaticPhysicsNode courtNode
	 */
	private String propertiesFile = "properties.txt";
	private final int scenarioWidth = 160;
	private final int scenarioHeigth = 30;
	private final int scenarioDepth = 120;
	private final int courtWidht = 8;
	private final int courtDepth = 80;
	private final int courtHeight = 1;
	private final float courtToWall = 6f;
	private final float wallDepth = 0.25f;
	private DisplaySystem displaySystem;
	private Node rootNode;
	private Camera camera;
	private LightState lightState;
	private PhysicsSpace physicsSpace;
	private TenPin tenPin;
	private BowlingBall bowlingBall;
	private Date shotFinished = null;
	private final float separation = 5;
	private Node barNode;
	private Node sofaNode1;
	private Node sofaNode2;
	private Node tableNode;

	public Scenario(DisplaySystem displaySystem, Node rootNode, Camera camera,
			LightState lightState, PhysicsSpace physicsSpace) {
		this.displaySystem = displaySystem;
		this.rootNode = rootNode;
		this.camera = camera;
		this.lightState = lightState;
		this.physicsSpace = physicsSpace;
		this.staticNode = this.physicsSpace.createStaticNode();
		rootNode.attachChild(staticNode);
		properties = new Properties();

		// InputStream in = Scenario.class.getClassLoader().getResourceAsStream(
		// propertiesFile);
		// if (in == null) {
		// // File not found! (Manage the problem)
		// }
		// Properties props = new java.util.Properties();
		// try {
		// props.load(in);
		// } catch (IOException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		try {
			properties.load(new FileInputStream(propertiesFile));
		} catch (Exception e) {
			System.out.println("!!!!!!!!!!!!!!!!!!Properties File not Found: "
					+ propertiesFile);
		}
		createBackWall();
		createFrontWall();
		createLeftWall();
		createRightWall();
		createFloor();
		createRoof();

		createScenario(scenarioWidth / 2, true);
		float courtStep = courtWidht + 2 * bowlingBall.getRadius() + separation;
		createScenario(scenarioWidth / 2 + 3 * courtStep, false);
		createScenario(scenarioWidth / 2 + 2 * courtStep, false);
		createScenario(scenarioWidth / 2 + courtStep, false);
		createScenario(scenarioWidth / 2 - courtStep, false);
		createScenario(scenarioWidth / 2 - 2 * courtStep, false);
		createScenario(scenarioWidth / 2 - 3 * courtStep, false);
		initCamera();
		initLights();
		setMaterialContacts();
		staticNode.generatePhysicsGeometry();

	}

	private void createFrontWall() {
		StaticPhysicsNode frontWallNode = physicsSpace.createStaticNode();
		rootNode.attachChild(frontWallNode);
		final Box visualBox = new Box("BackWall", new Vector3f(),
				scenarioWidth / 2, scenarioHeigth / 2, 0.5f);
		frontWallNode.attachChild(visualBox);

		frontWallNode.setLocalTranslation(new Vector3f(scenarioWidth / 2,
				scenarioHeigth / 2, scenarioDepth));

		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);

		frontWallNode.setMaterial(Material.CONCRETE);
		frontWallNode.setModelBound(new BoundingBox());
		frontWallNode.updateModelBound();
		frontWallNode.setRenderState(ms);
		frontWallNode.generatePhysicsGeometry();

	}

	private void createRoof() {
		StaticPhysicsNode roofNode = physicsSpace.createStaticNode();
		rootNode.attachChild(roofNode);
		final Box visualBox = new Box("Roof", new Vector3f(),
				scenarioWidth / 2, scenarioDepth / 2, wallDepth / 2);
		roofNode.attachChild(visualBox);

		roofNode.setLocalRotation(new Quaternion(new float[] {
				(float) Math.PI / 2, 0, 0 }));
		roofNode.setLocalTranslation(new Vector3f(scenarioWidth / 2,
				scenarioHeigth, scenarioDepth / 2));
		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);
		roofNode.setMaterial(Material.CONCRETE);
		roofNode.setRenderState(ms);
		roofNode.setModelBound(new BoundingBox());
		roofNode.updateModelBound();

		Texture t1 = TextureManager.loadTexture(Runner.class.getClassLoader()
				.getResource(properties.getProperty("IMGSDIR") + "floor.jpg"),
				Texture.MinificationFilter.Trilinear,
				Texture.MagnificationFilter.Bilinear);

		TextureState ts1 = displaySystem.getRenderer().createTextureState();
		ts1.setTexture(t1);

		roofNode.setRenderState(ts1);
		roofNode.generatePhysicsGeometry();
	}

	private void createScenario(float xPosition, boolean isPlayable) {
		if (isPlayable) {
			createPins(xPosition);
			createBowlingBall(xPosition);
		}
		createCourt(xPosition);
		createGutters(xPosition);
		createBackCourt(xPosition);
		createThrowPlatform(xPosition);
	}

	private void createThrowPlatform(float xPosition) {
		StaticPhysicsNode courtNode = physicsSpace.createStaticNode();
		rootNode.attachChild(courtNode);
		final Box visualBox = new Box("platform", new Vector3f(), courtWidht
				/ 2 + 2 * bowlingBall.getRadius() + 1.77f, 6, 1.25f);
		courtNode.attachChild(visualBox);

		courtNode.setLocalRotation(new Quaternion(new float[] {
				(float) -Math.PI / 2, 0, 0 }));
		courtNode.setLocalTranslation(new Vector3f(xPosition, 0, courtToWall
				+ courtDepth + 4));

		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);
		courtNode.setRenderState(ms);
		courtNode.setModelBound(new BoundingBox());
		courtNode.updateModelBound();

		Texture t1 = TextureManager.loadTexture(
				Runner.class.getClassLoader().getResource(
						properties.getProperty("IMGSDIR") + "sideWall.jpg"),
				Texture.MinificationFilter.Trilinear,
				Texture.MagnificationFilter.Bilinear);

		TextureState ts1 = displaySystem.getRenderer().createTextureState();
		ts1.setTexture(t1);

		courtNode.setMaterial(Material.WOOD);

		courtNode.setRenderState(ts1);
		courtNode.generatePhysicsGeometry();

	}

	private void createBackCourt(float position) {
		StaticPhysicsNode backCourtNode = physicsSpace.createStaticNode();
		rootNode.attachChild(backCourtNode);
		Box visualBox = new Box("LeftWall", new Vector3f(), .9f, 3, 9);
		visualBox.setLocalTranslation(new Vector3f(position - (courtWidht / 2)
				- (2 * bowlingBall.getRadius()) - 1.5f, 3, 3));
		backCourtNode.attachChild(visualBox);
		visualBox = new Box("LeftWall", new Vector3f(), .9f, 3, 9);
		visualBox.setLocalTranslation(new Vector3f(position + (courtWidht / 2)
				+ (2 * bowlingBall.getRadius()) + 1.5f, 3, 3));
		backCourtNode.attachChild(visualBox);

		visualBox = new Box("LeftWall", new Vector3f(), courtWidht, 5, 9);
		visualBox.setLocalTranslation(new Vector3f(position, 10, 3));
		backCourtNode.attachChild(visualBox);
		Helpers.setTexture(backCourtNode, properties.getProperty("TEXDIR")
				+ "logo.png", displaySystem);
		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.black);
		backCourtNode.setMaterial(Material.CONCRETE);
		backCourtNode.setRenderState(ms);
		backCourtNode.setModelBound(new BoundingBox());
		backCourtNode.updateModelBound();
		backCourtNode.generatePhysicsGeometry();

	}

	private void setMaterialContacts() {

		tenPin.changeContactMaterial(getBowlingBall().getMaterial(), 0f, 0f);
		tenPin.changeContactMaterial(tenPin.getPinMaterial(), 0.1f, 0f);
		tenPin.changeContactMaterial(Material.WOOD, 0.3f, 0);
		tenPin.changeContactMaterial(Material.CONCRETE, 0.3f, 0.1f);
		tenPin.changeContactMaterial(Material.IRON, 0, 0);

		bowlingBall.changeContactMaterial(tenPin.getPinMaterial(), 0f, 0f);
		bowlingBall.changeContactMaterial(Material.WOOD, 0.2f, 0);
		bowlingBall.changeContactMaterial(Material.CONCRETE, 0.5f, 0.1f);
		bowlingBall.changeContactMaterial(Material.IRON, 0, 0);

	}

	private void createGutters(float xPosition) {
		PhysicsNode gutterNode;
		Gutter leftGutter = new Gutter(bowlingBall.getRadius() + 0.2f,
				courtDepth, physicsSpace, false);
		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.black);
		gutterNode = leftGutter.getGutterNode();
		gutterNode.setMaterial(Material.IRON);
		gutterNode.setRenderState(ms);
		rootNode.attachChild(gutterNode);
		gutterNode.getLocalTranslation().set(
				new Vector3f(xPosition - courtWidht / 2 - 2
						* (bowlingBall.getRadius() + 0.2f), courtHeight,
						courtDepth / 2 + courtToWall));

		Gutter rightGutter = new Gutter(bowlingBall.getRadius() + 0.2f,
				courtDepth, physicsSpace, true);
		gutterNode = rightGutter.getGutterNode();
		gutterNode.setMaterial(Material.IRON);
		gutterNode.setRenderState(ms);
		rootNode.attachChild(gutterNode);
		gutterNode.getLocalTranslation().set(
				new Vector3f(xPosition + courtWidht / 2, courtHeight,
						courtDepth / 2 + courtToWall));
		// rootNode.attachChild(gutterNode)
		// Cylinder cylinder1 = new Cylinder("cil1", 10, 10, 0.2f, courtDepth);
		// cylinder1.setloca
		// gutterNode.attachChild(cylinder1);

	}

	private void createBowlingBall(float xPosition) {
		bowlingBall = new BowlingBall(new Vector3f(xPosition, 10f, courtDepth),
				physicsSpace, rootNode, displaySystem, properties
						.getProperty("TEXDIR")
						+ "ballTexture.png");

		bowlingBall.dontMove();

	}

	private void createPins(float xPosition) {

		tenPin = new TenPin(properties.getProperty("MODELDIR") + "pin.3ds",
				properties.getProperty("TEXDIR") + "pin.jpg", displaySystem,
				physicsSpace, rootNode, new Vector3f(xPosition, 2,
						courtToWall + 3), 1, 1);
		// tenPin.attach(rootNode);

	}

	private void createCourt(float xPosition) {
		StaticPhysicsNode courtNode = physicsSpace.createStaticNode();
		rootNode.attachChild(courtNode);
		final Box visualBox = new Box("Court", new Vector3f(), courtWidht / 2,
				courtDepth / 2, (float) courtHeight);
		courtNode.attachChild(visualBox);

		courtNode.setLocalRotation(new Quaternion(new float[] {
				(float) -Math.PI / 2, 0, 0 }));
		courtNode.setLocalTranslation(new Vector3f(xPosition, 0, courtDepth / 2
				+ courtToWall));
		Helpers.setTexture(courtNode, properties.getProperty("IMGSDIR")
				+ "courtFloor.jpg", displaySystem);
		MaterialState materialState = displaySystem.getRenderer()
				.createMaterialState();

		materialState.setAmbient(new ColorRGBA(0.8f, 0.8f, 0.2f, 1.0f));
		materialState.setDiffuse(new ColorRGBA(0.1f, 0.5f, 0.8f, 1.0f));
		materialState.setSpecular(ColorRGBA.black);
		materialState.setShininess(100f);
		materialState.setEmissive(ColorRGBA.black);
		materialState.setEnabled(true);

		courtNode.setRenderState(materialState);

		courtNode.setModelBound(new BoundingBox());
		courtNode.updateModelBound();

		// Texture t1 = TextureManager.loadTexture(Runner.class.getClassLoader()
		// .getResource(
		// properties.getProperty("IMGSDIR") + "courtFloor.jpg"),
		// Texture.MinificationFilter.Trilinear,
		// Texture.MagnificationFilter.Bilinear);
		//
		// TextureState ts1 = displaySystem.getRenderer().createTextureState();
		// ts1.setTexture(t1);
		// courtNode.setRenderState(ts1);

		courtNode.setMaterial(Material.WOOD);
		courtNode.updateRenderState();

		courtNode.generatePhysicsGeometry();
	}

	private void initLights() {
		// lightState.detachAll();

		// LightState lightState =
		// displaySystem.getRenderer().createLightState();

		((PointLight) lightState.get(0)).setLocation(new Vector3f(80, 40, 80));
		((PointLight) lightState.get(0)).setAmbient(ColorRGBA.white);
		// lightState.setTwoSidedLighting(true);
		lightState.setEnabled(true);
		lightState.setGlobalAmbient(ColorRGBA.white);
		// PointLight pointLight = new PointLight();
		//
		// pointLight.setEnabled(true);
		// pointLight.setLocation(new Vector3f(-10, scenarioHeigth / 2,
		// scenarioDepth + 10));
		// lightState.attach(pointLight);
		// rootNode.setRenderState(lightState);

	}

	private void initCamera() {
		camera.setLocation(new Vector3f(scenarioWidth / 2, scenarioHeigth / 2,
				scenarioDepth));

	}

	private void createBackWall() {
		StaticPhysicsNode backWallNode = physicsSpace.createStaticNode();
		rootNode.attachChild(backWallNode);
		final Box visualBox = new Box("BackWall", new Vector3f(),
				scenarioWidth / 2, scenarioHeigth / 2, 0.5f);
		backWallNode.attachChild(visualBox);

		backWallNode.setLocalTranslation(new Vector3f(scenarioWidth / 2,
				scenarioHeigth / 2, 0));

		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);

		backWallNode.setMaterial(Material.CONCRETE);
		backWallNode.setModelBound(new BoundingBox());
		backWallNode.updateModelBound();
		backWallNode.setRenderState(ms);
		backWallNode.generatePhysicsGeometry();
	}

	private void createLeftWall() {
		StaticPhysicsNode leftWallNode = physicsSpace.createStaticNode();
		rootNode.attachChild(leftWallNode);
		final Box visualBox = new Box("LeftWall", new Vector3f(),
				scenarioDepth / 2, scenarioHeigth / 2, wallDepth / 2);
		leftWallNode.attachChild(visualBox);

		leftWallNode.setLocalRotation(new Quaternion(new float[] { 0,
				(float) -Math.PI / 2, 0 }));
		leftWallNode.setLocalTranslation(new Vector3f(0, scenarioHeigth / 2,
				scenarioDepth / 2));

		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);
		leftWallNode.setMaterial(Material.CONCRETE);
		leftWallNode.setRenderState(ms);
		leftWallNode.setModelBound(new BoundingBox());
		leftWallNode.updateModelBound();

		Texture t1 = TextureManager.loadTexture(
				Runner.class.getClassLoader().getResource(
						properties.getProperty("IMGSDIR") + "sideWall.jpg"),
				Texture.MinificationFilter.Trilinear,
				Texture.MagnificationFilter.Bilinear);

		TextureState ts1 = displaySystem.getRenderer().createTextureState();
		ts1.setTexture(t1);

		leftWallNode.setRenderState(ts1);
		leftWallNode.generatePhysicsGeometry();

	}

	private void createRightWall() {
		StaticPhysicsNode rightWallNode = physicsSpace.createStaticNode();
		rootNode.attachChild(rightWallNode);
		final Box visualBox = new Box("RightWall", new Vector3f(),
				scenarioDepth / 2, scenarioHeigth / 2, wallDepth / 2);
		rightWallNode.attachChild(visualBox);

		rightWallNode.setLocalRotation(new Quaternion(new float[] { 0,
				(float) -Math.PI / 2, 0 }));
		rightWallNode.setLocalTranslation(new Vector3f(scenarioWidth,
				scenarioHeigth / 2, scenarioDepth / 2));

		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);
		rightWallNode.setMaterial(Material.CONCRETE);
		rightWallNode.setRenderState(ms);
		rightWallNode.setModelBound(new BoundingBox());
		rightWallNode.updateModelBound();

		Texture t1 = TextureManager.loadTexture(
				Runner.class.getClassLoader().getResource(
						properties.getProperty("IMGSDIR") + "sideWall.jpg"),
				Texture.MinificationFilter.Trilinear,
				Texture.MagnificationFilter.Bilinear);

		TextureState ts1 = displaySystem.getRenderer().createTextureState();
		ts1.setTexture(t1);

		rightWallNode.setRenderState(ts1);
		rightWallNode.generatePhysicsGeometry();
	}

	public void createFloor() {
		StaticPhysicsNode floorNode = physicsSpace.createStaticNode();
		rootNode.attachChild(floorNode);
		final Box visualBox = new Box("Floor", new Vector3f(),
				scenarioWidth / 2, scenarioDepth / 2, wallDepth / 2);
		floorNode.attachChild(visualBox);

		floorNode.setLocalRotation(new Quaternion(new float[] {
				(float) Math.PI / 2, 0, 0 }));
		floorNode.setLocalTranslation(new Vector3f(scenarioWidth / 2, 0,
				scenarioDepth / 2));
		MaterialState ms = displaySystem.getRenderer().createMaterialState();
		ms.setEmissive(ColorRGBA.white);
		floorNode.setMaterial(Material.CONCRETE);
		floorNode.setRenderState(ms);
		floorNode.setModelBound(new BoundingBox());
		floorNode.updateModelBound();

		Texture t1 = TextureManager.loadTexture(
				Runner.class.getClassLoader().getResource(
						properties.getProperty("IMGSDIR") + "Wood_Bam.jpg"),
				Texture.MinificationFilter.Trilinear,
				Texture.MagnificationFilter.Bilinear);

		TextureState ts1 = displaySystem.getRenderer().createTextureState();
		ts1.setTexture(t1);

		floorNode.setRenderState(ts1);
		floorNode.generatePhysicsGeometry();
	}

	public void reset(boolean reattach) {
		tenPin.reset(rootNode, reattach);
		bowlingBall.reset();
		bowlingBall.getBallNode().setAffectedByGravity(false);
	}

	public boolean shootFinished() {

		if (shotFinished != null) {
			Date now = new Date();
			if (now.getTime() - shotFinished.getTime() > 4000) {
				shotFinished = null;
				return true;
			} else {
				return false;
			}
		}
		if (bowlingBall.getBallNode().getLocalTranslation().getZ() < 6) {
			shotFinished = new Date();
			return false;
		}
		return false;
	}

	public boolean shotAnalize(boolean firstShot, Scoring scoring) {
		System.out.println("Actual first shoot:" + firstShot);
		ArrayList<Integer> fallPins = tenPin.getPinsDown(courtToWall);
		boolean nextFirstShoot;
		int down = fallPins.size();
		if (down == 10) {
			reset(!firstShot);
			nextFirstShoot = true;
		} else {
			for (Integer pinPos : fallPins) {
				rootNode.detachChild(tenPin.getPinNode(pinPos));
			}
			nextFirstShoot = !firstShot;
		}
		if (firstShot) {
			scoring.addPointsInFirst(down);
		} else {
			scoring.addPointsShootFinished(down);
			reset(!firstShot);
			System.out.println("SCORING:" + scoring);
		}
		return nextFirstShoot;

	}

	public boolean gameFinish(Scoring scoring) {
		if (scoring.getShoot() == 10) {
			return true;
		}
		return false;

	}

	public void generateHighDetails() {
		displayBar();
		displaySofa1(30);
		displaySofa2(45);
		displayTable();
	}

	private void displayTable() {
		if (tableNode == null) {
			tableNode = Helpers.getNodeFrom3DS(properties
					.getProperty("MODELDIR")
					+ "table.3ds", "table", rootNode);
			tableNode.setLocalScale(0.005f);
			Quaternion rotation = tableNode.getLocalRotation();
			tableNode.setLocalRotation(rotation.add(new Quaternion(new float[] {
					(float) (-Math.PI / 2), 0, 0 })));
			tableNode.setLocalTranslation(tableNode.getLocalTranslation().add(
					15, 3.5f, 35));
			tableNode.setModelBound(new BoundingBox());

			tableNode.setCullHint(CullHint.Never);
			tableNode.updateModelBound();
			rootNode.attachChild(tableNode);

			rootNode.updateRenderState();
		} else {
			rootNode.attachChild(tableNode);
		}

	}

	public void generateLowDetails() {
		if (barNode != null) {
			rootNode.detachChild(barNode);
			rootNode.detachChild(sofaNode1);
			rootNode.detachChild(sofaNode2);
			rootNode.detachChild(tableNode);
		}
	}

	private void displayBar() {

		if (barNode == null) {
			barNode = Helpers.getNodeFrom3DS(properties.getProperty("MODELDIR")
					+ "bar.3ds", "bar", rootNode);
			barNode.setLocalScale(0.1f);
			Quaternion rotation = barNode.getLocalRotation();
			barNode.setLocalRotation(rotation.add(new Quaternion(new float[] {
					(float) (-Math.PI / 2), (float) (Math.PI / 2), 0 })));
			barNode.setLocalTranslation(barNode.getLocalTranslation().add(0, 6,
					10));
			barNode.setModelBound(new BoundingBox());
			barNode.setCullHint(CullHint.Never);
			barNode.updateModelBound();
			rootNode.attachChild(barNode);

			rootNode.updateRenderState();
		} else {
			rootNode.attachChild(barNode);
		}
	}

	private void displaySofa1(int zPosition) {

		if (sofaNode1 == null) {
			sofaNode1 = Helpers.getNodeFrom3DS(properties
					.getProperty("MODELDIR")
					+ "sofa.3ds", "sofa", rootNode);
			sofaNode1.setLocalScale(0.15f);
			Quaternion rotation = sofaNode1.getLocalRotation();
			sofaNode1.setLocalRotation(rotation.add(new Quaternion(new float[] {
					(float) (-Math.PI / 2), 0, 0 })));
			sofaNode1.setLocalTranslation(sofaNode1.getLocalTranslation().add(
					-8, 3.5f, zPosition));
			sofaNode1.setModelBound(new BoundingBox());

			sofaNode1.setCullHint(CullHint.Never);
			sofaNode1.updateModelBound();
			rootNode.attachChild(sofaNode1);

			rootNode.updateRenderState();
		} else {
			rootNode.attachChild(sofaNode1);
		}
	}

	private void displaySofa2(int zPosition) {

		if (sofaNode2 == null) {
			sofaNode2 = Helpers.getNodeFrom3DS(properties
					.getProperty("MODELDIR")
					+ "sofa.3ds", "sofa", rootNode);
			sofaNode2.setLocalScale(0.15f);
			Quaternion rotation = sofaNode2.getLocalRotation();
			sofaNode2.setLocalRotation(rotation.add(new Quaternion(new float[] {
					(float) (-Math.PI / 2), 0, 0 })));
			sofaNode2.setLocalTranslation(sofaNode2.getLocalTranslation().add(
					-8, 3.5f, zPosition));
			sofaNode2.setModelBound(new BoundingBox());

			sofaNode2.setCullHint(CullHint.Never);
			sofaNode2.updateModelBound();
			rootNode.attachChild(sofaNode2);

			rootNode.updateRenderState();
		} else {
			rootNode.attachChild(sofaNode2);
		}
	}

	public TenPin getTenPin() {
		return tenPin;
	}

	public void setTenPin(TenPin tenPin) {
		this.tenPin = tenPin;
	}

	public BowlingBall getBowlingBall() {
		return bowlingBall;
	}

	public void setBowlingBall(BowlingBall bowlingBall) {
		this.bowlingBall = bowlingBall;
	}

	public Vector3f getCourtInit() {
		return new Vector3f(scenarioWidth / 2, 0, courtDepth);
	}

	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	public StaticPhysicsNode getStaticNode() {
		return staticNode;
	}

	public void setStaticNode(StaticPhysicsNode staticNode) {
		this.staticNode = staticNode;
	}

	public String getPropertiesFile() {
		return propertiesFile;
	}

	public void setPropertiesFile(String propertiesFile) {
		this.propertiesFile = propertiesFile;
	}

	public DisplaySystem getDisplaySystem() {
		return displaySystem;
	}

	public void setDisplaySystem(DisplaySystem displaySystem) {
		this.displaySystem = displaySystem;
	}

	public Node getRootNode() {
		return rootNode;
	}

	public void setRootNode(Node rootNode) {
		this.rootNode = rootNode;
	}

	public Camera getCamera() {
		return camera;
	}

	public void setCamera(Camera camera) {
		this.camera = camera;
	}

	public LightState getLightState() {
		return lightState;
	}

	public void setLightState(LightState lightState) {
		this.lightState = lightState;
	}

	public PhysicsSpace getPhysicsSpace() {
		return physicsSpace;
	}

	public void setPhysicsSpace(PhysicsSpace physicsSpace) {
		this.physicsSpace = physicsSpace;
	}

	public int getScenarioWidth() {
		return scenarioWidth;
	}

	public int getScenarioHeigth() {
		return scenarioHeigth;
	}

	public int getScenarioDepth() {
		return scenarioDepth;
	}

	public int getCourtWidht() {
		return courtWidht;
	}

	public int getCourtDepth() {
		return courtDepth;
	}

	public int getCourtHeight() {
		return courtHeight;
	}

	public float getWallDepth() {
		return wallDepth;
	}

}
